package com.hfzy.ihk.web.websocket.support;

import com.hfzy.ihk.common.util.string.StringUtil;
import com.hfzy.ihk.web.websocket.constant.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.WebSocketSession;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by Administrator on 2016/11/20.
 *
 * @author wws
 *
 * 1、webSocket 连接保存
 * 2、
 *
 *
 */
public final class WebSocketManager {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketManager.class);



    /**来自浏览器的连接 *********************************************************************************
    //----------------------------key:token, value:webSocket*/
    public static ConcurrentHashMap<String,WebSocketSession> browserTokenWebSocketSessionMap = new ConcurrentHashMap<>(10000);


    /**
     * 来自电信呼叫设备机器的map链接
     */
    public static ConcurrentHashMap<String,WebSocketSession> swxServerIdWebSocketSessionMap = new ConcurrentHashMap<>(1000);

    /** -----------用于解决app返回的状态能发送回发起外呼的那个页面---
     * 结构：    < userId:token, webSocket>
     * 所以：
     *
     * 传送给app的外呼任务,必须携带下面的参数：
     * userId,token
     * sessionId  -->保证能根据sessionId更新数据
     *
     * */
    public static ConcurrentHashMap<String,WebSocketSession> browserUserTokenWebSocketSessionMap = new ConcurrentHashMap<>(10000);

    /**-----------------用于检测用户使用多台电脑外呼---------------<zyUserId, <machineId,list:webSocket>>*/
    private static Map<String,Map<String,List<WebSocketSession>>> browserUserMahineWebSocketSessionsMap = new ConcurrentHashMap<>(10000);

    public static Map<String, Map<String, List<WebSocketSession>>> getBrowserUserMahineWebSocketSessionsMap() {
        return browserUserMahineWebSocketSessionsMap;
    }



    /**添加*/
    public static boolean addBrowserUserMachineWebSocketSession(String userId, String machineId, WebSocketSession webSocketSession){

        if(StringUtil.isEmpty(userId) ||
                StringUtil.isEmpty(machineId) ||
                !StringUtil.isNumeric(userId) ){
            return false;
        }

        Map<String,List<WebSocketSession>> machineSessionListMap = browserUserMahineWebSocketSessionsMap.get(userId);

        if(machineSessionListMap == null)
            machineSessionListMap = new ConcurrentHashMap<>();

        List<WebSocketSession> webSocketSessionList = machineSessionListMap.get(machineId);
        if(webSocketSessionList == null)
            webSocketSessionList = new CopyOnWriteArrayList<>();

        webSocketSessionList.add(webSocketSession);

        machineSessionListMap.put(machineId,webSocketSessionList);

        browserUserMahineWebSocketSessionsMap.put(userId,machineSessionListMap);

        return true;
    }
    /**删除用户所有机器的连接数据*/
    public static boolean removeBrowserUserMachineWebSocketSession(String userId){
        if(StringUtil.isEmpty(userId)||
                !StringUtil.isNumeric(userId)){
            return false;
        }
        browserUserMahineWebSocketSessionsMap.remove(userId);
        return true;
    }
    /**删除用户某机器上连接数据*/
    public static boolean removeBrowserUserMachineAllWebSocketSession(String userId,String machineId){
        if(StringUtil.isEmpty(userId) ||
                StringUtil.isEmpty(machineId) ||
                !StringUtil.isNumeric(userId) ){
            return false;
        }

        Map<String,List<WebSocketSession>> machineSessionListMap = browserUserMahineWebSocketSessionsMap.get(userId);

        if(machineSessionListMap != null)
            machineSessionListMap.remove(machineId);

        return true;
    }
    /** 当前用户数*/
    public static Integer getBrowserUserSize(){
        return browserUserMahineWebSocketSessionsMap.size();
    }

    /** 获取某用户连接服务器的机器数*/
    public static Integer getBrowserUserUseMachineSize(String userId){

        if(StringUtil.isEmpty(userId)||!StringUtil.isNumeric(userId)){
            return -1;
        }

        Map<String,List<WebSocketSession>> machineSessionListMap = browserUserMahineWebSocketSessionsMap.get(userId);

        return machineSessionListMap == null? 0 : machineSessionListMap.size();
    }

    /** 获取某用户连接服务器的机器连接映射*/
    public static Map<String,List<WebSocketSession>> getBrowserMachineSessionMap(String userId){

        if(StringUtil.isEmpty(userId)||!StringUtil.isNumeric(userId)){
            return null;
        }

        Map<String,List<WebSocketSession>> machineSessionListMap = browserUserMahineWebSocketSessionsMap.get(userId);

        return machineSessionListMap;
    }
    /** 获取某用户连接数据情况*/
    public static String getBrowserMachineSessionSizeDesc(String userId){

        if(StringUtil.isEmpty(userId)||!StringUtil.isNumeric(userId)){
            return null;
        }

        Map<String,List<WebSocketSession>> machineSessionListMap = browserUserMahineWebSocketSessionsMap.get(userId);

        if(machineSessionListMap==null || machineSessionListMap.isEmpty())
            return "";

        List<String> rs= new ArrayList<>();

        for (Map.Entry<String,List<WebSocketSession>> entry : machineSessionListMap.entrySet()){

            int sessionSize = entry.getValue() == null ? 0:entry.getValue().size();

            rs.add(StringUtil.strConnect("机器码:",entry.getKey(),",连接数:",String.valueOf(sessionSize)));
        }
        return String.join(",",rs);
    }

    /**获取用户某机器的webSocket连接数*/
    public static List<WebSocketSession> getBrowserUserMachineSessionList(String userId,String machineId){

        if(StringUtil.isEmpty(userId)||!StringUtil.isNumeric(userId)){
            return null;
        }

        Map<String,List<WebSocketSession>> machineSessionListMap = browserUserMahineWebSocketSessionsMap.get(userId);

        return machineSessionListMap == null?null:machineSessionListMap.get(machineId);
    }

    /**获取用户某机器的webSocket连接数*/
    public static Integer getBrowserUserMachineConnectionSize(String userId,String machineId){

        if(StringUtil.isEmpty(userId)||!StringUtil.isNumeric(userId)){
            return -1;
        }

        Map<String,List<WebSocketSession>> machineSessionListMap = browserUserMahineWebSocketSessionsMap.get(userId);

        if(machineSessionListMap == null || machineSessionListMap.isEmpty())
            return 0;

        List<WebSocketSession> socketSessionList=machineSessionListMap.get(machineId);

        if(socketSessionList==null || socketSessionList.isEmpty())
            return 0;

        return machineSessionListMap.get(machineId).size();
    }

    /*******************************插件的websocket******************************************************************************
    //-----------------------------key:zyUserId, value:webSocket*/
    public static Map<String, WebSocketSession> browserUserWebSocketSession4ChromePluginMap = new ConcurrentHashMap<String, WebSocketSession>(10000);

    /**************************************app的连接 ********************************************************

    /***--------------------------------key:userId或mac, value:webSocket*/
    public volatile static ConcurrentHashMap<String,WebSocketSession> appUserIdOrMacWebSocketSessionMap = new ConcurrentHashMap<>(10000);

    /**------------------------------其他api----------------------------------------*/
    /**清除用户浏览器webSocket连接信息*/
    public static void removeUserBrowserWebSocketSession(String userId, String token, String machineId, WebSocketSession currentSession){

        logger.info("before remove user browser webSocketSession,userId:{},machineId:{},连接情况:{}",
                userId,machineId,getBrowserMachineSessionSizeDesc(userId));

        browserTokenWebSocketSessionMap.remove(token);
        browserUserTokenWebSocketSessionMap.remove(userId+token);

        /*获取用户所有机器的连接《machineId,sessionList》*/
        Map<String,List<WebSocketSession>> machineWebSocketListMap = browserUserMahineWebSocketSessionsMap.get(userId);

        if(machineWebSocketListMap == null || machineWebSocketListMap.isEmpty())
            return;

        List<WebSocketSession> webSocketSessionList = machineWebSocketListMap.get(machineId);

        /*从该机器移除webSocket对象*/
        if(webSocketSessionList != null)
            webSocketSessionList.remove(currentSession);

        /*移除连接后，该机器没有连接了，删除machineWebSocketListMap中该机器entry*/
        if(webSocketSessionList == null || webSocketSessionList.isEmpty()) {
            machineWebSocketListMap.remove(machineId);
        }

        logger.info("after remove user browser webSocketSession,userId:{},machineId:{},连接情况:{}",
                userId,machineId,getBrowserMachineSessionSizeDesc(userId));
    }

    /**
     * 检查用户App是否已连接
     * @return 正常返回webSocket对象
     * */
    public static WebSocketSession appHasConnected(String userId){

        //使用MAC来连接webSocket,非正式环境要转换
//        userIdOrPhoneMac = tansUserId2PhoneMac(userIdOrPhoneMac);

        WebSocketSession session = appUserIdOrMacWebSocketSessionMap.get(userId);

        if(session == null || !session.isOpen()){
            logger.debug("check app websocket connect:userId:{},session==null || 非打开状态",userId);
            return null;
        }
        return session;
    }

    public static boolean checkIsTest(WebSocketSession session){

        if(session==null){
            return false;
        }

        String isTest = (String)session.getAttributes().get("isTest");
        if(Constants.TRUE.equals(isTest))
            return true;

        return false;
    }

    public static String createTestUserId(String userId){
        return StringUtil.strConnect("0000",userId);
    }

    /*要兼容演示*/
    public static ConcurrentHashMap<String,String> userIdToPhoneMac = new ConcurrentHashMap<>(10000);
    //id,userId,enroll_number
          /*1	29	00006
            2	31	00008
            3	39	00016
            4	40	00017
            5	41	00018
            6	45	00022
            7	47	00024
            8	103	00080
            9	479	00458
            10	491	00470
            11	492	00471
            12	190	00169
            13	194	00173
            14	201	00180
            15	207	00186
            16	256	00235
            17	273	00252
            18	317	00296
            19	24710	24711
            20	388	00367
            21	24871	24872
            22	407	00386
            23	416	00395
            24	1256	01236*/

    /*public static String tansUserId2PhoneMac(String userId){

        if(Constants.SYSTEM_ENV_PRO.equals(PublicConfig.SYSTEM_ENV)) {
            return userId;
        }

        String phoneMac =null;

        //使用redis，使用方便，只需要设置一次；而使用内存则需要2个项目都去设置
        phoneMac = RedisUtils.getHash("userId2Mac", userId);
        logger.debug(PublicConfig.SYSTEM_ENV +" userIdToPhoneMac:userId:" + userId + "-> mac:" + phoneMac);

        if (phoneMac != null) {
            return phoneMac;
        }else
            return userId;
    }
*/
}
